package aidturith.ihm.panel.table;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import aidturith.Constant;
import aidturith.db.beans.Alias;
import aidturith.db.beans.Game;
import aidturith.db.beans.Serie;
import aidturith.db.hibernate.HibernateUtil;
import aidturith.ihm.action.go.GoToSerieAction;
import aidturith.ihm.action.go.GoToSubtitleAction;
import aidturith.ihm.component.ButtonColumn;
import aidturith.ihm.component.ButtonImage;
import aidturith.ihm.component.FilterTextField;
import aidturith.ihm.component.Table;
import aidturith.ihm.panel.proto.TablePanel;

/**
 * Liste les séries.
 */
public class ListGames extends TablePanel {

	private static final long serialVersionUID = 1L;

	private Action goToSubtitle;
	private Action goToSerie;

	/**
	 * Constructeur.
	 * @param applet
	 * @throws IOException
	 */
	// TODO bouger les colonnes, confirmation si non vide
	public ListGames() throws IOException {
		super();
		setLayout(new BorderLayout());

		// model
		// TODO change header
		String[] TABLE_HEADER = {"Nom", "Série", "Année", "Nombre de musiques"};
		setTABLE_HEADER(TABLE_HEADER);
		setModel(new DefaultTableModel(populateModel(), getTABLE_HEADER()));
		getModel().addTableModelListener(this);

		// table
		setTable(new Table(getModel()));
		getTable().setPreferredScrollableViewportSize(getTable().getPreferredSize());
		getTable().setFillsViewportHeight(true);
		getTable().putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

		// columns
		for(int i=0; i<TABLE_HEADER.length; i++)
			switchToLabel(i);

		// TODO corresponding action
		goToSubtitle = new GoToSubtitleAction(this);
		new ButtonColumn(getTable(), goToSubtitle, 0);

		goToSerie = new GoToSerieAction(this);
		new ButtonColumn(getTable(), goToSerie, 1);

		// selection listener
		ListSelectionModel listSelectionModel = getTable().getSelectionModel();
		listSelectionModel.addListSelectionListener(this);
		getTable().setSelectionModel(listSelectionModel);

		// sort
		setSorter(new TableRowSorter<DefaultTableModel>(getModel()));
		getTable().setRowSorter(getSorter());

		// scroll
		setScrollPane(new JScrollPane(getTable()));
		getScrollPane().setPreferredSize(Constant.TABLE_SIZE);
		add(getScrollPane(), BorderLayout.CENTER);

		// locks
		// TODO change locks
		ArrayList<Boolean> list = new ArrayList<>();
		list.add(true);
		list.add(true);
		list.add(false);
		list.add(false);
		((Table) getTable()).setIsEditable(list);


		// shortcuts
		mapShortcuts();

		// buttons
		setBottom_jp(new JPanel());

		setFilter_jtf(new FilterTextField(this));
		getBottom_jp().add(getFilter_jtf());

		setEdit_jb(new ButtonImage("lock.png"));
		getEdit_jb().addActionListener(this);
		getBottom_jp().add(getEdit_jb());

		setAdd_jb(new ButtonImage("add.png"));
		getAdd_jb().addActionListener(this);
		getAdd_jb().setEnabled(false);
		getBottom_jp().add(getAdd_jb());

		setDelete_jb(new ButtonImage("delete.png"));
		getDelete_jb().addActionListener(this);
		getDelete_jb().setEnabled(false);
		getBottom_jp().add(getDelete_jb());

		add(getBottom_jp(), BorderLayout.SOUTH);
	}

	/*
		Session session = HibernateUtil.getSession();
		ArrayList<Object> list1 = (ArrayList<Object>) session.createCriteria(Serie.class).list();
		switchToAutoComplete(1, list1);
		session.close();
	 */

	@Override
	@SuppressWarnings("unchecked")
	public Object[][] populateModel() {
		Session session = HibernateUtil.getSession();

		// TODO change type
		List<Game> resultats = session.createCriteria(Game.class).list();
		Object[][] data = new Object[resultats.size()][getTABLE_HEADER().length];

		// TODO change columns
		for(int i = 0; i < resultats.size(); i++) {
			data[i][0] = resultats.get(i);
			data[i][1] = resultats.get(i).getSerie();
			data[i][2] = resultats.get(i).getGame_year();
			data[i][3] = resultats.get(i).getSubtitles().size();
		}

		session.close();
		if(Constant.DEBUG) System.out.println("build table from database..");
		return data;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void initColumn(boolean lock) {
		// TODO change column types
		// unlock
		if(!lock) {
			switchToLabel(0);
			switchToLabel(2);

			Session session = HibernateUtil.getSession();
			ArrayList<Object> list1 = (ArrayList<Object>) session.createCriteria(Serie.class).list();
			for(Alias a : (ArrayList<Alias>) session.createCriteria(Alias.class).add(Restrictions.isNotNull("serie")).list())
				list1.add(a.getAlias_name());
			switchToAutoComplete(1, list1);
			session.close();
			System.out.println("switch to autocomplete");

			ArrayList<Boolean> list = new ArrayList<>();
			list.add(true);
			list.add(true);
			list.add(true);
			list.add(false);
			((Table) getTable()).setIsEditable(list);
		}
		// lock
		else {
			new ButtonColumn(getTable(), goToSubtitle, 0);
			new ButtonColumn(getTable(), goToSerie, 1);

			System.out.println("switch to lock");

			ArrayList<Boolean> list = new ArrayList<>();
			list.add(true);
			list.add(true);
			list.add(false);
			list.add(false);
			((Table) getTable()).setIsEditable(list);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource().equals(getEdit_jb())) {
			// unlock
			initColumn(isEditing());
			if(!isEditing()) {
				((ButtonImage) getEdit_jb()).setIcon("unlock.png");
				setEditing(true);
				getAdd_jb().setEnabled(true);
				if(getSelected_object() != null)
					getDelete_jb().setEnabled(true);
				repaint();
			}
			// lock
			else {
				((ButtonImage) getEdit_jb()).setIcon("lock.png");
				setEditing(false);
				getAdd_jb().setEnabled(false);
				getDelete_jb().setEnabled(false);
				repaint();
			}
		}
		else if(e.getSource().equals(getAdd_jb())) {
			getFilter_jtf().clearFilter();
			addRow("");
		}
		else if(e.getSource().equals(getDelete_jb()))
			deleteRow();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void tableChanged(TableModelEvent e) {
		if(!isLocked() && isEditing() && (getSelected_object() != null)) {
			int row = e.getFirstRow();
			int column = e.getColumn();
			String column_content = getModel().getValueAt(row, column).toString();
			if(Constant.DEBUG) System.out.println(getSelected_object()+" is now "+column_content);

			Session session = HibernateUtil.getSession();

			// TODO change type
			Transaction tx = session.beginTransaction();
			Game obj = ((Game) getSelected_object().get(0));
			obj.setGame_name(getModel().getValueAt(row, 0).toString());
			obj.setGame_year(Integer.valueOf(new String(""+getModel().getValueAt(row, 2))));

			if(getModel().getValueAt(row, 1) != null) {
				// check aliases too
				String serie = getModel().getValueAt(row, 1).toString();
				ArrayList<Serie> list = (ArrayList<Serie>) session.createCriteria(Serie.class)
						.add(Restrictions.like("serie_name", serie)).list();
				ArrayList<Alias> list_alias = (ArrayList<Alias>) session.createCriteria(Alias.class)
						.add(Restrictions.isNotNull("serie")).list();
				if(list.size() > 0)
					obj.setSerie(list.get(0));
				else if(list_alias.size() > 0)
					obj.setSerie(list_alias.get(0).getSerie());
				else {
					Serie new_serie = new Serie(serie);
					obj.setSerie(new_serie);
					session.save(new_serie);
				}
			}

			session.update(obj);
			tx.commit();

			session.close();

			updateTableInfo();
		}
	}

	@Override
	public void addRow(String name) {
		setLocked(true);
		// TODO change type
		Game new_object = new Game(name);
		Object[] row = {new_object, new_object.getSerie(), new_object.getGame_year(), new_object.getSubtitles().size()};

		getModel().addRow(row);

		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		session.save(new_object);
		tx.commit();
		session.close();
		setLocked(false);

		selectRow(getTable().getRowCount()-1);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		try {
			frame.add(new ListGames());
		} catch (IOException e) {
			e.printStackTrace();
		}
		frame.setVisible(true);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		/*try {
			frame.getContentPane().removeAll();
			frame.add(new ListSeries());
			frame.revalidate();
		} catch (IOException e) {
			e.printStackTrace();
		}*/
	}

}
